Seata

nacos 配置

先创建一个 seata 的 namespace 记录ID a9cfa2b3-71b8-4c99-8a8e-5c31f74787e3

下载 https://github.com/seata/seata

在 seata-develop\script\config-center 目录下

config.txt 根据自己的需要修改

我的修改内容为

store 开头都删掉(配置从 nacos 读取了 这个应该也没什么用)

添加 service.vgroupMapping.服务名=default 有几个添加几个 ( 1.4.2 是这样的格式 旧版是其他格式

等后面项目启动报错了再加也行

执行 nacos/nacos-config.sh

sh nacos-config.sh -h 192.168.101.222 -p 8848 -g SEATA_GROUP -t a9cfa2b3-71b8-4c99-8a8e-5c31f74787e3 -u nacos -w nacos

把 config.txt 的内容导入到 nacos 中 结果如图

其实内容也就是

手动一个个添加到nacos也行

docker 部署 seata

docker pull seataio/seata-server:1.4.2

docker run –name seata -p 8091:8091 -d seataio/seata-server:1.4.2

docker cp seata:/seata-server /home/dockerdata/seata —–把 seata 的配置文件放到 /home/dockerdata/seata 中

docker stop seata

docker rm seata

修改 /home/dockerdata/seata/seata-server/resources/registry.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"

nacos {
application = "seata-server"
serverAddr = "192.168.101.222:8848"
group = "SEATA_GROUP"
namespace = "a9cfa2b3-71b8-4c99-8a8e-5c31f74787e3"
cluster = "default"
username = "nacos"
password = "nacos"
}
}

config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"

nacos {
serverAddr = "192.168.101.222:8848"
namespace = "a9cfa2b3-71b8-4c99-8a8e-5c31f74787e3"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
dataId = "seataServer.properties" }
}

配置后 重新运行一个以 /home/dockerdata/seata/seata-server/resources 为配置目录的 容器

docker run -d –name seata-server -it -p 8091:8091 -e SEATA_IP=192.168.101.222 -e SEATA_CONFIG_NAME=file:/root/seata/config/registry -v /home/dockerdata/seata/seata-server/resources:/root/seata/config –net=bridge –restart=always seataio/seata-server:1.4.2;

到 nacos 的服务中查看 服务列表 是否有 seata-server (记得切换到 seata 命名空间

SpringCloud 整合 Seata

Maven引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.2.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.2</version>
//排除掉旧版本 引入最新的 1.4.2
</dependency>

配置yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: my_test_tx_group #此处配置自定义的seata事务分组名称
enable-auto-data-source-proxy: true #开启数据库代理
#不需要手动去替换 datasource
config:
type: nacos
nacos:
namespace: a9cfa2b3-71b8-4c99-8a8e-5c31f74787e3
server-addr: 192.168.101.222:8848
group: SEATA_GROUP
username: nacos
password: nacos
registry:
type: nacos
nacos:
application: seata-server
server-addr: 192.168.101.222:8848
namespace: a9cfa2b3-71b8-4c99-8a8e-5c31f74787e3
username: nacos
password: nacos

创建 undo_log 表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'increment id',
`branch_id` bigint NOT NULL COMMENT 'branch transaction id',
`xid` varchar(100) NOT NULL COMMENT 'global transaction id',
`context` varchar(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` longblob NOT NULL COMMENT 'rollback info',
`log_status` int NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` datetime NOT NULL COMMENT 'create datetime',
`log_modified` datetime NOT NULL COMMENT 'modify datetime',
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8 COMMENT='AT transaction mode undo table';
SET FOREIGN_KEY_CHECKS=1;

碰到的问题

Jackson格式化 Cannot construct instance of java.time.LocalDateTime (no Creators, like de

解决过程

尝试 给 Jackson 添加

.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule());

无效

看源码找到 JacksonUndoLogParser

private final ObjectMapper mapper = new ObjectMapper();

原来用的自己创建的 ObjectMapper 难怪 给Spring的 ObjectMapper 添加 JavaTimeModule 没有效果

在源码中找切换 jackson 的方式 看到原来读取配置 client.undo.logSerialization=jackson

然后记录在 undo_log 表的 context 字段中 serializer=jackson&compressorType=NONE

在执行回滚时反序列化是根据 serializer=jackson 查找 Parser

在插入 undo_log 时 是根据 配置 client.undo.logSerialization

修改 client.undo.logSerialization 即可切换 Parser 有 fastjson jackson kryo protostuff 这些可以选择

换为 fastjson 嗯 还是 时间转换异常 错误变成 Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]]

┻━┻︵╰(‵□′)╯︵┻━┻

解决方法

覆盖 seata 的 JacksonUndoLogParser ( 自己定义一个一模一样的包名 和 类名 然后把 seata中的 JacksonUndoLogParser 复制进去 修改其中部分代码

在 init() 中 添加

mapper.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule());

解决 (๑•̀ㅂ•́)و✧